package com.ruoyi.system.util;

import com.ruoyi.system.domain.VApplicationInfoScore;

import java.lang.reflect.Field;
import java.util.*;
import java.util.stream.Collectors;



public class PersonMerger {

    // 定义合并策略接口
    interface MergeStrategy<T> {
        T merge(T value1, T value2);
    }

    // 实现一些具体的合并策略
    private static final Map<Class<?>, MergeStrategy<?>> mergeStrategies = new HashMap<>();

    static {
        mergeStrategies.put(String.class, (MergeStrategy<String>) String::concat); // 注意：这里应该使用更合适的字符串合并方式，如使用逗号分隔
        mergeStrategies.put(int.class, (MergeStrategy<Integer>) Integer::sum);
        mergeStrategies.put(double.class, (MergeStrategy<Double>) Double::sum);
        // 可以为其他类型添加合并策略
    }

    // 使用反射和Stream API来合并Person对象的静态方法
    public static VApplicationInfoScore mergePersons(List<VApplicationInfoScore> persons) throws IllegalAccessException {
        if (persons.isEmpty()) {
            throw new IllegalArgumentException("Person list cannot be empty");
        }

        VApplicationInfoScore mergedPerson = new VApplicationInfoScore();

        // 通过反射获取Person类的所有字段
        Field[] fields = VApplicationInfoScore.class.getDeclaredFields();

        for (Field field : fields) {
            field.setAccessible(true); // 允许访问私有字段

            Class<?> fieldType = field.getType();

            // 如果该字段类型有定义的合并策略
            if (mergeStrategies.containsKey(fieldType)) {
                // 使用Stream API和合并策略来合并字段值
                Object mergedValue = persons.stream()
                        .map(person -> {
                            try {
                                return field.get(person);
                            } catch (IllegalAccessException e) {
                                throw new RuntimeException(e);
                            }
                        })
                        .collect(Collectors.collectingAndThen(
                                Collectors.toList(),
                                list -> {
                                    // 对列表应用合并策略（这里需要特殊处理，因为合并策略接受两个参数）
                                    // 我们可以使用reduce方法，但需要注意初始值和合并函数
                                    // 对于String，简单的concat可能不是最佳合并方式（会导致所有字符串连接在一起）
                                    // 这里为了演示，我们仍然使用concat，但实际应用中应该使用更合适的逻辑
                                    // 例如，对于String，可以使用Collectors.joining(",")来合并
                                    if (fieldType == String.class) {
                                        // 使用逗号分隔字符串（或选择其他合适的合并方式）
                                        return list.stream()
                                                .distinct()
                                                .filter(name -> name != null)
                                                .map(Object::toString) // 将Integer转换为String
                                                .collect(Collectors.joining(","));
                                    } else {
                                        // 对于数值类型，我们可以使用reduce来求和（或求平均等）
                                        // 注意：这里我们使用了Object类型作为reduce的初始值，并进行了类型转换
                                        // 这在Java中是类型不安全的，但在这个特定的例子中，由于我们知道字段类型，所以可以接受
                                        // 在实际应用中，应该使用更安全的方法来处理类型
                                        @SuppressWarnings("unchecked")
                                        MergeStrategy<Object> strategy = (MergeStrategy<Object>) mergeStrategies.get(fieldType);
                                        return list.stream()
                                                .reduce((v1, v2) -> strategy.merge(v1, v2))
                                                .orElseThrow(() -> new IllegalStateException("Reduce operation resulted in an empty list"));
                                    }
                                }
                        ));

                // 设置合并后的值到结果对象中
                field.set(mergedPerson, mergedValue);
            }
            // 如果该字段类型没有定义的合并策略，则跳过（或可以选择抛出异常）
        }

        return mergedPerson;
    }

}